package com.woniuxy.interceptor;


import com.alibaba.fastjson.JSON;
import com.woniuxy.util.JWTUtil;
import com.woniuxy.util.ResponseCode;
import com.woniuxy.util.ResponseData;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 检验用户登录状态栏拦截
 * 1.实现HandlerInterceptor接口,放入容器,并且重写preHandle方法
 * 2.在springmvc中配置拦截器
 * 实现步骤(对请求做jwt参数的认证)
 * 1.获取请求jwt参数  没带拦截器拦截
 * 2.用系统的密钥解密   解不开拦截
 * 3.对比redis的JWT    前端jwt==redis的jwt
 * 对比不成功(redis的jwt过期):拦截
 * 4.放行
 */
@Component
@AllArgsConstructor
public class LoginInterceptor implements HandlerInterceptor {
//    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取请求jwt参数(请求头中)
        String headerJWT = request.getHeader("authorization");
        response.setContentType("application/json;charset=utf-8");
        if (headerJWT == null) {
            //给前端响应
            //如果直接把对象放入打印流中,默认用jdk的方式序列化转成字符串,需要把对象转为json字符串
            response.getWriter().print(JSON.toJSONString(ResponseData.fail(ResponseCode.NO_LOGIN)));
            return false;
        }//拦截
        //2.用系统的密钥解密
        if (!JWTUtil.decode(headerJWT)) {
            response.getWriter().print(JSON.toJSONString(ResponseData.fail(ResponseCode.NO_LOGIN)));
            return false;
        }

        //3.对比redis的JWT
        Map<String, Object> userMap = JWTUtil.getUserMap(headerJWT);
        Long userId = (Long) userMap.get("id");
        String redisJWT = stringRedisTemplate.opsForValue().get("jwt"+userId);
        if (!headerJWT.equals(redisJWT)){
            response.getWriter().print(JSON.toJSONString(ResponseData.fail(ResponseCode.NO_LOGIN)));
            return false;
        }
        //给redis的jwt续期
        stringRedisTemplate.expire("jwt"+userId,15, TimeUnit.DAYS);
        return true;
    }
}
